﻿using Common.Communication;
using Common.Device.DeviceDb;
using Common.Device.Interfaces;
using Common.Tool.DataTools;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading;
using System.Threading.Tasks;
using System.Xml.Linq;

namespace DianYuan.DC
{
    public class UDP3305S_ESerialPort:SerialPortBase,IDianYuan
    {
        public string Name { get; set; }
        public UDP3305S_ESerialPort(UseDevice device) : base(device.port, Convert.ToInt32(device.parameter), timeout: 1500)
        {
            Name = device.name;
        }
        public Result<bool> SetOn(double vol, double cur = 0, int channel = 1)
        {
            lock (this)
            {
                string command = "";
                var result = new Result<bool>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"通道{channel}设置输出{vol}V,{cur}A");
                command = CmdApply(channel, vol, cur);
                write = Write(command);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(100);
                command = CmdGetApply(channel);
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || read.Value.Count(o => o == ',') != 2)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                string[] value = read.Value.Split(',');
                if (value.Length != 3)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                float V = float.Parse(value[1]);
                float A = float.Parse(value[2]);
                if (V != vol || A != cur)
                {
                    result.IsSucceed = false;
                    result.Err = "设置输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, $"通道{channel}打开输出");
                command = CmdOutPutOn(channel);
                write = Write(command);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "打开输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(100);
                command = CmdGetOutPut(channel);
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || !read.Value.Contains(CmdOn))
                {
                    result.IsSucceed = false;
                    result.Err = "打开输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "设置输出成功");
                return result.EndTime();
            }
        }
        public Result<bool> SetOff(int channel = 1)
        {
            lock (this)
            {
                string command = "";
                var result = new Result<bool>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"通道{channel}关闭输出");
                command = CmdOutPutOff(channel);
                write = Write(command);
                if (!write.IsSucceed)
                {
                    result.IsSucceed = false;
                    result.Err = "关闭输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                Thread.Sleep(100);
                command = CmdGetOutPut(channel);
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || !read.Value.Contains(CmdOff))
                {
                    result.IsSucceed = false;
                    result.Err = "关闭输出失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                AppendInfo(Name, "关闭输出成功");
                return result.EndTime();
            }
        }
        public Result<double> GetVoltage(int channel = 1)
        {
            lock (this)
            {
                string command = "";
                double vol = 0f;
                var result = new Result<double>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"通道{channel}读取当前电压");
                command = CmdGetVolt(channel);
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || !double.TryParse(read.Value, out vol))
                {
                    result.IsSucceed = false;
                    result.Err = "读取当前电压失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                result.Value = vol;
                AppendResult(Name, DataConvert.ToUnit(vol, "F3") + "V");
                return result.EndTime();
            }
        }
        public Result<double> GetCurrent(int channel = 1)
        {
            lock (this)
            {
                string command = "";
                double cur = 0f;
                var result = new Result<double>();
                var write = new Result();
                var read = new Result<string>();
                AppendInfo(Name, $"通道{channel}读取当前电流");
                command = CmdGetCurr(channel);
                //发送指令并返回
                read = WriteThenRead(command);
                if (!read.IsSucceed || !double.TryParse(read.Value, out cur))
                {
                    result.IsSucceed = false;
                    result.Err = "读取当前电流失败";
                    AppendTip(Name, result.Err);
                    return result.EndTime();
                }
                result.Value = cur;
                AppendResult(Name, DataConvert.ToUnit(cur, "F3") + "A");
                return result.EndTime();
            }
        }
        public Result<double> GetPower(int channel = 1)
        {
            lock (this)
            {
                Result<double> result = new Result<double>();
                result.IsSucceed = false;
                result.Err = "暂不支持";
                return result.EndTime();
            }
        }
        string CmdApply(int channel, double vol, double cur) => $"APPL CH{channel},{vol.ToString("F2")}V,{cur.ToString("F3")}A\r\n";
        string CmdGetApply(int channel) => $"APPLy? CH{channel}\r\n";
        string CmdOutPutOn(int channel) => $"OUTPut:STATe CH{channel}, ON\r\n";
        string CmdOutPutOff(int channel) => $"OUTPut:STATe CH{channel}, OFF\r\n";
        string CmdGetOutPut(int channel) => $"OUTPut:STATe? CH{channel}\r\n";
        string CmdOn => "ON";
        string CmdOff => "OFF";
        string CmdGetVolt(int channel) => $"MEAS:VOLT? CH{channel}\r\n";
        string CmdGetCurr(int channel) => $"MEAS:CURR? CH{channel}\r\n";
    }
}
